import CryptoJS from 'crypto-js'

interface Tool {
    screen: (element: HTMLElement) => void
    objCopy: <T>(obj: T) => T
    dateFormat: (date: Date | string | number, fmt?: string) => string
    groupSeparator: (num: number | string) => string
    crypto: {
        MD5: (data: string) => string
        BASE64: {
            encrypt: (data: string) => string
            decrypt: (cipher: string) => string
        }
        AES: {
            encrypt: (data: string, secretKey: string, config?: { iv?: string; mode?: string; padding?: string }) => string
            decrypt: (cipher: string, secretKey: string, config?: { iv?: string; mode?: string; padding?: string }) => string
        }
    }
    toCamelCase: (str: string) => string
}

export const tool: Tool = {
    // 全屏
    screen: function (element: HTMLElement) {
        const isFull = !!document.fullscreenElement
        if (isFull) {
            if (document.exitFullscreen) {
                document.exitFullscreen().then((r) => console.log(r))
            }
        } else if (element.requestFullscreen) {
            element.requestFullscreen().then((r) => console.log(r))
        }
    },

    // 复制对象
    objCopy: function <T>(obj: T): T {
        return JSON.parse(JSON.stringify(obj)) as T
    },

    // 日期格式化
    dateFormat: function (date: Date | string | number, fmt: string = 'yyyy-MM-dd hh:mm:ss'): string {
        date = new Date(date)
        const o: { [key: string]: number | string } = {
            'M+': date.getMonth() + 1, // 月份
            'd+': date.getDate(), // 日
            'h+': date.getHours(), // 小时
            'm+': date.getMinutes(), // 分
            's+': date.getSeconds(), // 秒
            'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
            S: date.getMilliseconds() // 毫秒
        }
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
        }
        for (const k in o) {
            if (new RegExp('(' + k + ')').test(fmt)) {
                fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? (o[k] as string) : ('00' + o[k]).substr(('' + o[k]).length))
            }
        }
        return fmt
    },

    // 千分符
    groupSeparator: function (num: number | string): string {
        num = num.toString()
        if (!num.includes('.')) {
            num += '.'
        }
        return num
            .replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
                return $1 + ','
            })
            .replace(/\.$/, '')
    },

    // 常用加解密
    crypto: {
        // MD5加密
        MD5: function (data: string): string {
            return CryptoJS.MD5(data).toString()
        },
        // BASE64加解密
        BASE64: {
            encrypt: function (data: string): string {
                return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
            },
            decrypt: function (cipher: string): string {
                return CryptoJS.enc.Base64.parse(cipher).toString(CryptoJS.enc.Utf8)
            }
        },
        // AES加解密
        AES: {
            encrypt: function (data: string, secretKey: string, config: { iv?: string; mode?: string; padding?: string } = {}): string {
                if (secretKey.length % 8 !== 0) {
                    console.warn('[kitegoAdmin error]: 秘钥长度需为8的倍数，否则解密将会失败。')
                }
                const result = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(secretKey), {
                    iv: CryptoJS.enc.Utf8.parse(config.iv || ''),
                    mode: CryptoJS.mode['ECB'],
                    padding: CryptoJS.pad['Pkcs7']
                })
                return result.toString()
            },
            decrypt: function (cipher: string, secretKey: string, config: { iv?: string; mode?: string; padding?: string } = {}): string {
                const result = CryptoJS.AES.decrypt(cipher, CryptoJS.enc.Utf8.parse(secretKey), {
                    iv: CryptoJS.enc.Utf8.parse(config.iv || ''),
                    mode: CryptoJS.mode['ECB'],
                    padding: CryptoJS.pad['Pkcs7']
                })
                return CryptoJS.enc.Utf8.stringify(result)
            }
        }
    },

    // 自动转驼峰
    toCamelCase: function (str: string): string {
        // 替换所有的下划线或短横线为空格，然后使用正则替换首字母非大写字母前加空格为大写（并去除空格）
        return str
            .replace(/[-_/]+(.)?/g, function (match, p1) {
                return p1 ? p1.toUpperCase() : ''
            })
            .replace(/^./, function (str) {
                // 确保字符串的第一个字符是小写
                return str.toLowerCase()
            })
    }
}
